import java.util.ArrayList;
import java.util.List;

public class Test {
    // [参考资料](https://liaoxuefeng.com/books/java/generics/type-erasure/index.html)
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        Integer n = list.get(0); // 编译后实际变成：
        // Integer n = (Integer) list.get(0);

    }

}
// Rust 的泛型 → 编译期单态化
// 每个具体类型都生成一份专门机器码，运行时没有任何额外开销（零成本抽象）。
// Java 的泛型 → 编译期擦除 + 运行时强制类型转换
// 字节码里只剩 Object，每次取值都要做类型检查/转换，确实不是零成本

// Java 泛型 = 编译期类型推导 + 编译期擦除成 Object/边界类型
// 运行期只剩 Object 引用，唯一例外是数组仍带具体类型标签，
// 编译期
// 完成类型推导（T 被推断成 String 或其他边界类型）。
// 同时做类型检查，保证你把 String 当 String 用，把 Integer 当 Integer 用。
// 之后擦除所有泛型信息：代码里出现的 T 统一替换成它的最左边界（无界时就是 Object；有界如 <T extends Number> 则替换成 Number）。
// 运行期
// 没有真正的“泛型类型”对象；T 这一符号已消失。
// 只有普通的 Object/边界类型引用。
// 数组除外：Java 数组是 reified，运行时会携带元素类型标签。
// 因此对数组做元素赋值时，JVM 会动态检查实际元素类型与数组声明类型是否一致，不一致就抛 ArrayStoreException。
// 对集合、普通字段等非数组场景，运行期不再做任何类型检查，错了就等 ClassCastException 在使用时暴露。